#include "iec61850_server.h"
#include "hal_thread.h"
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
#include <libxml/parser.h>  
#include <libxml/xmlmemory.h>  
#include "static_model.h"
#include "pcs_modbus_registers.h"

#define REGISTERS_SIMULATOR_START 1000
#define REGISTERS_SIMULATOR_END 1078

#define REGISTERS_STATUS_START 1100
#define REGISTERS_STATUS_END 1107

#define REGISTERS_SYS1_START 3503
#define REGISTERS_SYS1_END 3594

#define REGISTERS_SYS2_START 6001
#define REGISTERS_SYS2_END 6043

#define REGISTERS_CONTROL_START 8000
#define REGISTERS_CONTROL_END 8002

#define REGISTERS_DEVICE_START 8100
#define REGISTERS_DEVICE_END 8100

RegisterBitMap switchInputStatus[] ={
    {0, 2, &iedModel_Sta_StatGGIO_IntIn1_stVal},
    {2, 1, &iedModel_Sta_StatGGIO_IntIn2_stVal},
    {3, 1, &iedModel_Sta_StatGGIO_IntIn3_stVal},
    {4, 1, &iedModel_Sta_StatGGIO_IntIn4_stVal},
    {5, 1, &iedModel_Sta_StatGGIO_IntIn5_stVal},
    {6, 2, &iedModel_Sta_StatGGIO_IntIn6_stVal},
    {8, 1, &iedModel_Sta_StatGGIO_IntIn7_stVal},
    {9, 1, &iedModel_Sta_StatGGIO_IntIn8_stVal},
    {10, 1, &iedModel_Sta_StatGGIO_IntIn9_stVal},
    {11, 1, &iedModel_Sta_StatGGIO_IntIn10_stVal},
    {12, 1, &iedModel_Sta_StatGGIO_IntIn11_stVal},
};

RegisterBitMap Warning1[] ={
    {0, 1, &iedModel_Sta_Wrn1GGIO_Wrn1_stVal},
    {1, 1, &iedModel_Sta_Wrn1GGIO_Wrn2_stVal},
    {2, 1, &iedModel_Sta_Wrn1GGIO_Wrn3_stVal},
    {3, 1, &iedModel_Sta_Wrn1GGIO_Wrn4_stVal},
    {4, 1, &iedModel_Sta_Wrn1GGIO_Wrn5_stVal},
    {5, 2, &iedModel_Sta_Wrn1GGIO_Wrn6_stVal},
    {6, 1, &iedModel_Sta_Wrn1GGIO_Wrn7_stVal},
    {7, 1, &iedModel_Sta_Wrn1GGIO_Wrn8_stVal},
    {8, 1, &iedModel_Sta_Wrn1GGIO_Wrn9_stVal},
    {9, 1, &iedModel_Sta_Wrn1GGIO_Wrn10_stVal},
    {10, 1, &iedModel_Sta_Wrn1GGIO_Wrn11_stVal},
    {11, 1, &iedModel_Sta_Wrn1GGIO_Wrn12_stVal},
    {12, 1, &iedModel_Sta_Wrn1GGIO_Wrn13_stVal},
    {13, 1, &iedModel_Sta_Wrn1GGIO_Wrn14_stVal},
    {14, 1, &iedModel_Sta_Wrn1GGIO_Wrn15_stVal},
    {15, 1, &iedModel_Sta_Wrn1GGIO_Wrn16_stVal},
};
RegisterBitMap Warning2[] ={
    {0, 1, &iedModel_Sta_Wrn2GGIO_Wrn1_stVal},
    {1, 1, &iedModel_Sta_Wrn2GGIO_Wrn2_stVal},
    {2, 1, &iedModel_Sta_Wrn2GGIO_Wrn3_stVal},
    {3, 1, &iedModel_Sta_Wrn2GGIO_Wrn4_stVal},
    {4, 1, &iedModel_Sta_Wrn2GGIO_Wrn5_stVal},
    {5, 2, &iedModel_Sta_Wrn2GGIO_Wrn6_stVal},
    {6, 1, &iedModel_Sta_Wrn2GGIO_Wrn7_stVal},
    {7, 1, &iedModel_Sta_Wrn2GGIO_Wrn8_stVal},
    {8, 1, &iedModel_Sta_Wrn2GGIO_Wrn9_stVal},
    {9, 1, &iedModel_Sta_Wrn2GGIO_Wrn10_stVal},
    {10, 1, &iedModel_Sta_Wrn2GGIO_Wrn11_stVal},
    {11, 1, &iedModel_Sta_Wrn2GGIO_Wrn12_stVal},
    {12, 1, &iedModel_Sta_Wrn2GGIO_Wrn13_stVal},
    {13, 1, &iedModel_Sta_Wrn2GGIO_Wrn14_stVal},
    {14, 1, &iedModel_Sta_Wrn2GGIO_Wrn15_stVal},
    {15, 1, &iedModel_Sta_Wrn2GGIO_Wrn16_stVal},
};
RegisterBitMap Warning3[] ={
    {0, 1, &iedModel_Sta_Wrn3GGIO_Wrn1_stVal},
    {1, 1, &iedModel_Sta_Wrn3GGIO_Wrn2_stVal},
    {2, 1, &iedModel_Sta_Wrn3GGIO_Wrn3_stVal},
    {3, 1, &iedModel_Sta_Wrn3GGIO_Wrn4_stVal},
    {4, 1, &iedModel_Sta_Wrn3GGIO_Wrn5_stVal},
    {5, 2, &iedModel_Sta_Wrn3GGIO_Wrn6_stVal},
    {6, 1, &iedModel_Sta_Wrn3GGIO_Wrn7_stVal},
    {7, 1, &iedModel_Sta_Wrn3GGIO_Wrn8_stVal},
    {8, 1, &iedModel_Sta_Wrn3GGIO_Wrn9_stVal},
    {9, 1, &iedModel_Sta_Wrn3GGIO_Wrn10_stVal},
    {10, 1, &iedModel_Sta_Wrn3GGIO_Wrn11_stVal},
    {11, 2, &iedModel_Sta_Wrn3GGIO_Wrn12_stVal},
    {13, 1, &iedModel_Sta_Wrn3GGIO_Wrn13_stVal},
    {14, 1, &iedModel_Sta_Wrn3GGIO_Wrn14_stVal},
};
RegisterBitMap Warning4[] ={
    {0, 1, &iedModel_Sta_Wrn4GGIO_Wrn1_stVal},
    {1, 1, &iedModel_Sta_Wrn4GGIO_Wrn2_stVal},
    {2, 1, &iedModel_Sta_Wrn4GGIO_Wrn3_stVal},
    {3, 1, &iedModel_Sta_Wrn4GGIO_Wrn4_stVal},
    {15, 1, &iedModel_Sta_Wrn4GGIO_Wrn5_stVal},
};

RegisterDesc recvArraySim[] = {
    {1000, 0.1, &iedModel_Sta_ACMMXU_PPV_phsAB_cVal_mag_f, NULL},
    {1001, 0.1, &iedModel_Sta_ACMMXU_PPV_phsBC_cVal_mag_f, NULL},
    {1002, 0.1, &iedModel_Sta_ACMMXU_PPV_phsCA_cVal_mag_f, NULL},
    {1003, 0.1, &iedModel_Sta_ACMMXU_A_phsA_cVal_mag_f, NULL},
    {1004, 0.1, &iedModel_Sta_ACMMXU_A_phsB_cVal_mag_f, NULL},
    {1005, 0.1, &iedModel_Sta_ACMMXU_A_phsC_cVal_mag_f, NULL},
    {1006, 0.01, &iedModel_Sta_ACMMXU_Hz_mag_f, NULL},
    {1007, 0.01, &iedModel_Sta_ACMMXU_W_phsA_cVal_mag_f, NULL},
    {1008, 0.01, &iedModel_Sta_ACMMXU_W_phsB_cVal_mag_f, NULL},
    {1009, 0.01, &iedModel_Sta_ACMMXU_W_phsC_cVal_mag_f, NULL},
    {1010, 0.01, &iedModel_Sta_ACMMXU_VAr_phsA_cVal_mag_f, NULL},
    {1011, 0.01, &iedModel_Sta_ACMMXU_VAr_phsB_cVal_mag_f, NULL},
    {1012, 0.01, &iedModel_Sta_ACMMXU_VAr_phsC_cVal_mag_f, NULL},
    {1013, 0.01, &iedModel_Sta_ACMMXU_VA_phsA_cVal_mag_f, NULL},
    {1014, 0.01, &iedModel_Sta_ACMMXU_VA_phsB_cVal_mag_f, NULL},
    {1015, 0.01, &iedModel_Sta_ACMMXU_VA_phsC_cVal_mag_f, NULL},
    {1016, 0.01, &iedModel_Sta_ACMMXU_PF_phsA_cVal_mag_f, NULL},
    {1017, 0.01, &iedModel_Sta_ACMMXU_PF_phsB_cVal_mag_f, NULL},
    {1018, 0.01, &iedModel_Sta_ACMMXU_PF_phsC_cVal_mag_f, NULL},
    {1019, 0.1, &iedModel_Sta_ACMMXU_PhV_phsA_cVal_mag_f, NULL},
    {1020, 0.1, &iedModel_Sta_ACMMXU_PhV_phsB_cVal_mag_f, NULL},
    {1021, 0.1, &iedModel_Sta_ACMMXU_PhV_phsC_cVal_mag_f, NULL},
    {1022, 0.1, &iedModel_Sta_MMDC_VolPsGnd_mag_f, NULL},
    {1023, 0.1, &iedModel_Sta_MMDC_VolNgGnd_mag_f, NULL},
    {1024, 0.1, &iedModel_Sta_DCMMXU_A_phsA_cVal_mag_f, NULL},
    {1025, 0.1, &iedModel_Sta_DCMMXU_A_phsB_cVal_mag_f, NULL},
    {1026, 0.1, &iedModel_Sta_DCMMXU_A_phsC_cVal_mag_f, NULL},
    {1027, 0.1, &iedModel_Sta_DCMMXU_PPV_phsAB_cVal_mag_f, NULL},
    {1028, 0.1, &iedModel_Sta_DCMMXU_PPV_phsBC_cVal_mag_f, NULL},
    {1029, 0.1, &iedModel_Sta_DCMMXU_PPV_phsCA_cVal_mag_f, NULL},
    {1030, 0.1, &iedModel_Sta_STMP_Tmp1_mag_f, NULL},
    {1031, 0.1, &iedModel_Sta_STMP_Tmp2_mag_f, NULL},
    {1032, 0.1, &iedModel_Sta_STMP_Tmp3_mag_f, NULL},
    {1039, 0.1, &iedModel_Sta_MMDC_Vol_mag_f, NULL},
    {1040, 0.1, &iedModel_Sta_MMDC_Amp_mag_f, NULL},
    {1065, 0.1, &iedModel_Sta_MMDC_Watt_mag_f, NULL},
    {1066, 0.1, &iedModel_Sta_DCMMXU_TotW_mag_f, NULL},
    {1067, 0.1, &iedModel_Sta_DCMMXU_TotVAr_mag_f, NULL},
    {1068, 0.1, &iedModel_Sta_DCMMXU_TotVA_mag_f, NULL},
    {1069, 0.1, &iedModel_Sta_STMP_Tmp_mag_f, NULL},
    {1070, 0.01, &iedModel_Sta_DCMMXU_W_phsA_cVal_mag_f, NULL},
    {1071, 0.01, &iedModel_Sta_DCMMXU_W_phsB_cVal_mag_f, NULL},
    {1072, 0.01, &iedModel_Sta_DCMMXU_W_phsC_cVal_mag_f, NULL},
    {1073, 0.01, &iedModel_Sta_DCMMXU_VAr_phsA_cVal_mag_f, NULL},
    {1074, 0.01, &iedModel_Sta_DCMMXU_VAr_phsB_cVal_mag_f, NULL},
    {1075, 0.01, &iedModel_Sta_DCMMXU_VAr_phsC_cVal_mag_f, NULL},
    {1076, 0.01, &iedModel_Sta_DCMMXU_VA_phsA_cVal_mag_f, NULL},
    {1077, 0.01, &iedModel_Sta_DCMMXU_VA_phsB_cVal_mag_f, NULL},
    {1078, 0.01, &iedModel_Sta_DCMMXU_VA_phsC_cVal_mag_f, NULL},
};

RegisterDesc recvArraySta[] = {
    /*BitMap*/
    {1100, 1, NULL, switchInputStatus},
    {1104, 1, NULL, Warning1},
    {1105, 1, NULL, Warning2},
    {1106, 1, NULL, Warning3},
    {1107, 1, NULL, Warning4},
};

RegisterDesc regArraySys1[] = {
    /*System*/
    {3503, 1, &iedModel_Sys_ArgGGIO_IASSO3503_setVal, NULL},
    {3504, 1, &iedModel_Sys_ArgGGIO_IASSO3504_setVal, NULL},
    {3505, 1, &iedModel_Sys_ArgGGIO_IASSO3505_setVal, NULL},
    {3506, 1, &iedModel_Sys_ArgGGIO_IASSO3506_setVal, NULL},
    {3507, 1, &iedModel_Sys_ArgGGIO_IASSO3507_setVal, NULL},
    {3508, 1, &iedModel_Sys_ArgGGIO_IASSO3508_setVal, NULL},
    {3509, 1, &iedModel_Sys_ArgGGIO_IASSO3509_setVal, NULL},
    {3510, 1, &iedModel_Sys_ArgGGIO_IASSO3510_setVal, NULL},
    {3511, 1, &iedModel_Sys_ArgGGIO_IASSO3511_setVal, NULL},
    {3512, 1, &iedModel_Sys_ArgGGIO_IASSO3512_setVal, NULL},
    {3513, 1, &iedModel_Sys_ArgGGIO_IASSO3513_setVal, NULL},
    {3514, 1, &iedModel_Sys_ArgGGIO_IASSO3514_setVal, NULL},
    {3515, 1, &iedModel_Sys_ArgGGIO_IASSO3515_setVal, NULL},
    /**/
    {3522, 1, &iedModel_Sys_ArgGGIO_IASSO3522_setVal, NULL},
    {3523, 1, &iedModel_Sys_ArgGGIO_IASSO3523_setVal, NULL},
    {3524, 1, &iedModel_Sys_ArgGGIO_IASSO3524_setVal, NULL},
    /**/
    {3527, 1, &iedModel_Sys_ArgGGIO_IASSO3527_setVal, NULL},
    {3528, 1, &iedModel_Sys_ArgGGIO_IASSO3528_setVal, NULL},
    {3529, 1, &iedModel_Sys_ArgGGIO_IASSO3529_setVal, NULL},
    /**/
    {3534, 1, &iedModel_Sys_ArgGGIO_IASSO3534_setVal, NULL},
    {3535, 1, &iedModel_Sys_ArgGGIO_IASSO3535_setVal, NULL},
    {3536, 1, &iedModel_Sys_ArgGGIO_IASSO3536_setVal, NULL},
    {3537, 1, &iedModel_Sys_ArgGGIO_IASSO3537_setVal, NULL},
    {3538, 1, &iedModel_Sys_ArgGGIO_IASSO3538_setVal, NULL},
    {3539, 1, &iedModel_Sys_ArgGGIO_IASSO3539_setVal, NULL},
    /**/
    {3550, 1, &iedModel_Sys_ArgGGIO_IASSO3550_setVal, NULL},
    {3551, 1, &iedModel_Sys_ArgGGIO_IASSO3551_setVal, NULL},
    {3552, 1, &iedModel_Sys_ArgGGIO_IASSO3552_setVal, NULL},
    {3553, 1, &iedModel_Sys_ArgGGIO_IASSO3553_setVal, NULL},
    {3554, 1, &iedModel_Sys_ArgGGIO_IASSO3554_setVal, NULL},
    /**/
    {3556, 1, &iedModel_Sys_ArgGGIO_IASSO3556_setVal, NULL},
    {3557, 1, &iedModel_Sys_ArgGGIO_IASSO3557_setVal, NULL},
    {3558, 1, &iedModel_Sys_ArgGGIO_IASSO3558_setVal, NULL},
    {3559, 1, &iedModel_Sys_ArgGGIO_IASSO3559_setVal, NULL},
    {3560, 1, &iedModel_Sys_ArgGGIO_IASSO3560_setVal, NULL},
    /**/
    {3563, 1, &iedModel_Sys_ArgGGIO_IASSO3563_setVal, NULL},
    /**/
    {3567, 1, &iedModel_Sys_ArgGGIO_IASSO3567_setVal, NULL},
    {3568, 1, &iedModel_Sys_ArgGGIO_IASSO3568_setVal, NULL},
    {3569, 0.1, &iedModel_Sys_ArgGGIO_IASSO3569_setMag_f, NULL},
    {3570, 0.1, &iedModel_Sys_ArgGGIO_IASSO3570_setMag_f, NULL},
    {3571, 1, &iedModel_Sys_ArgGGIO_IASSO3571_setVal, NULL},
    {3572, 0.001, &iedModel_Sys_ArgGGIO_IASSO3572_setMag_f, NULL},
    {3573, 0.001, &iedModel_Sys_ArgGGIO_IASSO3573_setMag_f, NULL},
    {3574, 1, &iedModel_Sys_ArgGGIO_IASSO3574_setVal, NULL},
    {3575, 1, &iedModel_Sys_ArgGGIO_IASSO3575_setVal, NULL},
    {3576, 1, &iedModel_Sys_ArgGGIO_IASSO3576_setVal, NULL},
    {3577, 0.01, &iedModel_Sys_ArgGGIO_IASSO3577_setMag_f, NULL},
    {3578, 0.01, &iedModel_Sys_ArgGGIO_IASSO3578_setMag_f, NULL},
    {3579, 0.01, &iedModel_Sys_ArgGGIO_IASSO3579_setMag_f, NULL},
    {3580, 0.01, &iedModel_Sys_ArgGGIO_IASSO3580_setMag_f, NULL},
    {3581, 0.01, &iedModel_Sys_ArgGGIO_IASSO3581_setMag_f, NULL},
    {3582, 0.01, &iedModel_Sys_ArgGGIO_IASSO3582_setMag_f, NULL},
    {3583, 0.01, &iedModel_Sys_ArgGGIO_IASSO3583_setMag_f, NULL},
    {3584, 0.01, &iedModel_Sys_ArgGGIO_IASSO3584_setMag_f, NULL},
    {3585, 0.01, &iedModel_Sys_ArgGGIO_IASSO3585_setMag_f, NULL},
    {3586, 0.01, &iedModel_Sys_ArgGGIO_IASSO3586_setMag_f, NULL},
    {3587, 0.01, &iedModel_Sys_ArgGGIO_IASSO3587_setMag_f, NULL},
    {3588, 0.01, &iedModel_Sys_ArgGGIO_IASSO3588_setMag_f, NULL},
    {3589, 0.01, &iedModel_Sys_ArgGGIO_IASSO3589_setMag_f, NULL},
    {3590, 0.01, &iedModel_Sys_ArgGGIO_IASSO3590_setMag_f, NULL},
    {3591, 0.01, &iedModel_Sys_ArgGGIO_IASSO3591_setMag_f, NULL},
    {3592, 0.01, &iedModel_Sys_ArgGGIO_IASSO3592_setMag_f, NULL},
    {3593, 0.01, &iedModel_Sys_ArgGGIO_IASSO3593_setMag_f, NULL},
    {3594, 0.01, &iedModel_Sys_ArgGGIO_IASSO3594_setMag_f, NULL},
};

RegisterDesc regArraySys2[] = {
    /**/
    {6001, 1, &iedModel_Sys_BatGGIO_IASSO6001_setVal, NULL},
    {6002, 1, &iedModel_Sys_BatGGIO_IASSO6002_setVal, NULL},
    {6003, 1, &iedModel_Sys_BatGGIO_IASSO6003_setVal, NULL},
    {6004, 1, &iedModel_Sys_BatGGIO_IASSO6004_setVal, NULL},
    /**/
    {6007, 1, &iedModel_Sys_BatGGIO_IASSO6007_setVal, NULL},
    {6008, 0.1, &iedModel_Sys_BatGGIO_IASSO6008_setMag_f, NULL},
    {6009, 0.1, &iedModel_Sys_BatGGIO_IASSO6009_setMag_f, NULL},
    {6010, 0.001, &iedModel_Sys_BatGGIO_IASSO6010_setMag_f, NULL},
    {6011, 1, &iedModel_Sys_BatGGIO_IASSO6011_setVal, NULL},
    {6012, 0.1, &iedModel_Sys_BatGGIO_IASSO6012_setMag_f, NULL},
    {6013, 0.001, &iedModel_Sys_BatGGIO_IASSO6013_setMag_f, NULL},
    {6014, 0.001, &iedModel_Sys_BatGGIO_IASSO6014_setMag_f, NULL},
    {6015, 1, &iedModel_Sys_BatGGIO_IASSO6015_setVal, NULL},
    {6016, 1, &iedModel_Sys_BatGGIO_IASSO6016_setVal, NULL},
    {6017, 1, &iedModel_Sys_BatGGIO_IASSO6017_setVal, NULL},
    /**/
    {6019, 0.1, &iedModel_Sys_BatGGIO_IASSO6019_setMag_f, NULL},
    {6020, 1, &iedModel_Sys_BatGGIO_IASSO6020_setVal, NULL},
    {6021, 0.1, &iedModel_Sys_BatGGIO_IASSO6021_setMag_f, NULL},
    {6022, 1, &iedModel_Sys_BatGGIO_IASSO6022_setVal, NULL},
    {6023, 0.001, &iedModel_Sys_BatGGIO_IASSO6023_setMag_f, NULL},
    {6024, 1, &iedModel_Sys_BatGGIO_IASSO6024_setVal, NULL},
    {6025, 1, &iedModel_Sys_BatGGIO_IASSO6025_setVal, NULL},
    {6026, 1, &iedModel_Sys_BatGGIO_IASSO6026_setVal, NULL},
    /**/
    {6031, 1, &iedModel_Sys_BatGGIO_IASSO6031_setVal, NULL},
    /**/
    {6033, 1, &iedModel_Sys_BatGGIO_IASSO6033_setVal, NULL},
    {6034, 0.1, &iedModel_Sys_BatGGIO_IASSO6034_setMag_f, NULL},
    {6035, 0.1, &iedModel_Sys_BatGGIO_IASSO6035_setMag_f, NULL},
    {6036, 1, &iedModel_Sys_BatGGIO_IASSO6036_setVal, NULL},
    {6037, 0.1, &iedModel_Sys_BatGGIO_IASSO6037_setMag_f, NULL},
    {6038, 0.1, &iedModel_Sys_BatGGIO_IASSO6038_setMag_f, NULL},
    {6039, 0.1, &iedModel_Sys_BatGGIO_IASSO6039_setMag_f, NULL},
    {6040, 0.1, &iedModel_Sys_BatGGIO_IASSO6040_setMag_f, NULL},
    {6041, 1, &iedModel_Sys_BatGGIO_IASSO6041_setVal, NULL},
    {6042, 0.1, &iedModel_Sys_BatGGIO_IASSO6042_setMag_f, NULL},
    {6043, 0.1, &iedModel_Sys_BatGGIO_IASSO6043_setMag_f, NULL},
};

RegisterDesc sendArrayCtrl[] = {
    {8000, 1, &iedModel_Ctr_CtrlGGIO_IASSO8000_setVal, NULL},
    {8001, 1, &iedModel_Ctr_CtrlGGIO_IASSO8001_setVal, NULL},
    {8002, 1, &iedModel_Ctr_CtrlGGIO_IASSO8002_setVal, NULL},
};
RegisterDesc sendArrayDev[] = {
    {8100, 1, &iedModel_Ctr_CtrlGGIO_IASSO8100_setVal, NULL},
};
ModbusRegisters modbusRegistersArray[] = {
{REGISTERS_SIMULATOR_START, REGISTERS_SIMULATOR_END, REG_RECV           , recvArraySim},
{REGISTERS_STATUS_START   , REGISTERS_STATUS_END   , REG_RECV           , recvArraySta},
{REGISTERS_SYS1_START     , REGISTERS_SYS1_END     , REG_RECV | REG_SEND, regArraySys1},
{REGISTERS_SYS2_START     , REGISTERS_SYS2_END     , REG_RECV | REG_SEND, regArraySys2},
{REGISTERS_CONTROL_START  , REGISTERS_CONTROL_END  , REG_SEND           , sendArrayCtrl},
{REGISTERS_DEVICE_START   , REGISTERS_DEVICE_END   , REG_SEND           , sendArrayDev},
};